
;======================================================================
;获取指定索引文本数据位置
Static_Text_Get_Item_Data_Addr
    LDA FC_Data_Count
    STA FC_Data_Index_L
    LDA #$00
    STA FC_Data_Index_H
    
    ASL FC_Data_Index_L
    ROL FC_Data_Index_H

    LDA #<Static_Text_Index
    CLC
    ADC FC_Data_Index_L
    STA FC_Data_Addr_L
    
    LDA #>Static_Text_Index
    ADC FC_Data_Index_H
    STA FC_Data_Addr_H

    LDY #$00
    LDA (FC_Data_Addr_L),Y
    PHA
    INY 
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Addr_H
    PLA
    STA FC_Data_Addr_L
    RTS

;======================================================================
;初始化静态文本
Static_Text_Init
    LDA #$00
    STA FC_Data_Count

    ;单条文本写入
Static_Text_Init.Write_Item
    
    ;获取文本数据地址
    JSR Static_Text_Get_Item_Data_Addr
    
    LDA PPU_STATUS
    LDA #$00
    STA PPU_CTRL
    
    ;没有内容则结束
    LDA FC_Data_Addr_L
    ORA FC_Data_Addr_H
    BEQ Static_Text_Init.End
    
    ;获取文本居中符号
    LDY #$00
    LDA (FC_Data_Addr_L),Y
    PHA
    
    ;获取文本位置高位
    LDY #$02
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Temp_H
    
    ;获取文本位置低位
    LDY #$01
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Temp_L
    
    PLA
    STA FC_Data_Index_L
    LDA FC_Data_Index_L
    BEQ Static_Text_Init.Write_PPU_Addr
    AND #STATIC_TEXT_VERTIVAL
    BEQ Static_Text_Init.Write_PPU_Mode
    
    ;PPU垂直写入
    LDA #$04
    STA PPU_CTRL
    
    ;PPU模式检查
Static_Text_Init.Write_PPU_Mode
    LDA FC_Data_Index_L
    AND #STATIC_TEXT_CENTER
    BEQ Static_Text_Init.Write_PPU_Addr
    
Static_Text_Init.Write_PPU_Center
    ;获取文本长度
    LDY #$03
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Index_L
    
    ;计算文本两边空余多少字符(每行32个字符, 减去显示文本长度后的剩余长度 / 2 = 当前行居中显示起始位置)
    LDA #$20
    SEC
    SBC FC_Data_Index_L
    LSR
    STA FC_Data_Index_L
    
    ;计算文本居中位置
    LDA FC_Data_Temp_L
    AND #$E0
    CLC
    ADC FC_Data_Index_L
    STA FC_Data_Temp_L
    
Static_Text_Init.Write_PPU_Addr
    LDA FC_Data_Temp_H
    STA PPU_ADDRESS
    LDA FC_Data_Temp_L
    STA PPU_ADDRESS
    
    LDY #$03
    LDA (FC_Data_Addr_L),Y
    TAX
    INY

    ;写入文本内存
    
Static_Text_Init.Write_Data
    STY FC_Data_Char_Index
    LDA (FC_Data_Addr_L),Y
    
    ;小写转大写
    CONVERT_TO_UPPERCASE
    
    STA FC_Data_Temp
    JSR Convert_Static_Tile
    BCS Static_Text_Init.Write_Char
    ;字符映射
    .IF CHAR_MAPPING_ENABLE
    TYA
    PHA
    
    LDY FC_Data_Temp
    LDA Char_Mapping_Data,Y
    STA FC_Data_Temp
    
    PLA
    TAY
    .ENDIF

Static_Text_Init.Write_Char
    LDA FC_Data_Temp
    STA PPU_DATA
    INY
    DEX
    BNE Static_Text_Init.Write_Data

Static_Text_Init.Continue
    INC FC_Data_Count
    JMP Static_Text_Init.Write_Item
    
Static_Text_Init.End
    RTS
    
;======================================================================
Convert_Static_Tile
    LDA FC_Data_Char_Index
    SEC
    SBC #$04
    STA FC_Data_Char_Index
    LDA FC_Data_Temp
    CMP #$20
    BNE Convert_Static_Tile.End
    TYA
    PHA
    LDA FC_Data_Temp_H
    PHA
    LDA FC_Data_Temp_L
    PHA
    
    LDA FC_Data_Temp_L
    CLC
    ADC #<Nametable_Data
    STA FC_Data_Temp_L
    LDA FC_Data_Temp_H
    AND #$03
    ADC #>Nametable_Data
    STA FC_Data_Temp_H
    
    LDA FC_Data_Temp_L
    CLC
    ADC FC_Data_Char_Index
    STA FC_Data_Temp_L
    LDA FC_Data_Temp_H
    ADC #$00
    STA FC_Data_Temp_H
    
    LDY #$00
    LDA (FC_Data_Temp_L),Y
    STA FC_Data_Temp
    PLA
    STA FC_Data_Temp_L
    PLA
    STA FC_Data_Temp_H
    PLA
    TAY
    SEC
    RTS
Convert_Static_Tile.End
    CLC
    RTS

;======================================================================
;写入文本PPU位置
Set_Text_Item_Pos
    LDA FC_Page_Item_Index
    ASL
    TAY
    LDA Game_Name_Pos + 1,Y
    STA FC_PPU_Buf_Addr,X
    INX
    LDA Game_Name_Pos,Y
    STA FC_PPU_Buf_Addr,X
    INX
    RTS

;======================================================================
;清除一条文本
Page_Text_Item_Clear
    LDX FC_PPU_Buf_Count
    
    ;获取上一页节目索引
    LDA FC_Page_Last_Index
    CLC
    ADC FC_Page_Item_Index
    BCS Page_Text_Item_Clear.End            ;最大节目索引超过255, 不处理
    
    CMP #GAME_COUNT - 1 ;与最大节目索引比较
    BCC Page_Text_Item_Clear.Item_Clear     ;小于最大节目索引
    BEQ Page_Text_Item_Clear.Item_Clear     ;等于最大节目索引
    BNE Page_Text_Item_Clear.End            ;大于最大节目索引
    
Page_Text_Item_Clear.Item_Clear
    ;写入清除模式
    LDA #PPU_WRITE_MODE_CNT_LINE
    STA FC_PPU_Buf_Addr,X
    INX
    
    ;写入文本PPU位置
    JSR Set_Text_Item_Pos
    
    ;写入文本长度
    LDA #$00
    STA FC_Data_Index_H
    LDA FC_Page_Last_Index
    CLC
    ADC FC_Page_Item_Index
    STA FC_Data_Index_L
    
    ;索引左移 1 位
    ASL FC_Data_Index_L
    ROL FC_Data_Index_H
    
    ;得到节目名列表起始地址(节目名列表 + 索引)
    LDA #<Game_Name_Index
    CLC
    ADC FC_Data_Index_L
    STA FC_Data_Addr_L
    LDA #>Game_Name_Index
    ADC FC_Data_Index_H
    STA FC_Data_Addr_H
    
    LDY #$00
    LDA (FC_Data_Addr_L),Y
    PHA
    INY
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Addr_H
    PLA
    STA FC_Data_Addr_L
    
    ;得到文本长度
    LDY #$00
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Count
    STA FC_PPU_Buf_Addr,X
    INX
    
    LDA FC_Page_Item_Index
    ASL
    TAY
    LDA Game_Name_Pos,Y
    CLC
    ADC #<Nametable_Data
    STA FC_Data_Addr_L
    INY
    LDA Game_Name_Pos,Y
    AND #$03
    ADC #>Nametable_Data
    STA FC_Data_Addr_H
    
    LDY #$00
Page_Text_Item_Clear.Write_Item_Data
    LDA (FC_Data_Addr_L),Y
    STA FC_PPU_Buf_Addr,X
    INX
    INY
    DEC FC_Data_Count
    BNE Page_Text_Item_Clear.Write_Item_Data
Page_Text_Item_Clear.End
    STX FC_PPU_Buf_Count
    RTS

;======================================================================
;写入一条文本
Page_Text_Item_Write
    LDX FC_PPU_Buf_Count

    ;获取当前页节目索引
    LDA FC_Page_Cur_Index
    CLC
    ADC FC_Page_Item_Index
    BCS Page_Text_Item_Write.End            ;最大节目索引超过255, 不处理
    
    CMP #GAME_COUNT - 1 ;与最大节目索引比较
    BCC Page_Text_Item_Write.Item_Write     ;小于最大节目索引
    BEQ Page_Text_Item_Write.Item_Write     ;等于最大节目索引
    BNE Page_Text_Item_Write.End            ;大于最大节目索引
    
Page_Text_Item_Write.Item_Write
    ;写入行模式
    LDA #PPU_WRITE_MODE_CNT_LINE
    STA FC_PPU_Buf_Addr,X
    INX
    
    ;写入文本PPU位置
    JSR Set_Text_Item_Pos
    
    ;写入文本长度
    LDA #$00
    STA FC_Data_Index_H
    LDA FC_Page_Cur_Index
    CLC
    ADC FC_Page_Item_Index
    STA FC_Data_Index_L
    
    ;索引左移 1 位
    ASL FC_Data_Index_L
    ROL FC_Data_Index_H
    
    ;得到节目名列表起始地址(节目名列表 + 索引)
    LDA #<Game_Name_Index
    CLC
    ADC FC_Data_Index_L
    STA FC_Data_Addr_L
    LDA #>Game_Name_Index
    ADC FC_Data_Index_H
    STA FC_Data_Addr_H
    
    LDY #$00
    LDA (FC_Data_Addr_L),Y
    PHA
    INY
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Addr_H
    PLA
    STA FC_Data_Addr_L
    
    LDY #$00
    LDA (FC_Data_Addr_L),Y
    STA FC_Data_Count
    STA FC_PPU_Buf_Addr,X
    INX
    INY
Page_Text_Item_Write.Write_Item_Data
    STY FC_Data_Char_Index
    LDA (FC_Data_Addr_L),Y
    
    ;小写转大写
    CONVERT_TO_UPPERCASE
    
    STA FC_Data_Temp
    JSR Convert_Bgk_Tile
    BCS Page_Text_Item_Write.Write_Char
    
    ;字符映射
    .IF CHAR_MAPPING_ENABLE
    TYA
    PHA
    
    LDA FC_Data_Temp
    TAY
    LDA Char_Mapping_Data,Y
    STA FC_Data_Temp
    
    PLA
    TAY
    .ENDIF
    
Page_Text_Item_Write.Write_Char
    LDA FC_Data_Temp
    STA FC_PPU_Buf_Addr,X
    INX
    INY
    DEC FC_Data_Count
    BNE Page_Text_Item_Write.Write_Item_Data
Page_Text_Item_Write.End
    STX FC_PPU_Buf_Count
    RTS

;======================================================================
Convert_Bgk_Tile
    LDA FC_Data_Temp
    CMP #$20
    BNE Convert_Bgk_Tile.End
    DEC FC_Data_Char_Index
    TYA
    PHA
    
    ;得到命名表数据地址
    LDA #<Nametable_Data
    STA FC_Data_Temp_L
    LDA #>Nametable_Data
    STA FC_Data_Temp_H
    
    LDA FC_Page_Item_Index
    ASL
    TAY
    LDA Game_Name_Pos,Y
    CLC
    ADC FC_Data_Temp_L
    STA FC_Data_Temp_L
    
    INY
    LDA Game_Name_Pos,Y
    AND #$03
    ADC FC_Data_Temp_H
    STA FC_Data_Temp_H
    
    ;得到字符位置数据
    LDA FC_Data_Temp_L
    CLC
    ADC FC_Data_Char_Index
    STA FC_Data_Temp_L
    LDA FC_Data_Temp_H
    ADC #$00
    STA FC_Data_Temp_H
    
    LDY #$00
    LDA (FC_Data_Temp_L),Y
    STA FC_Data_Temp
    PLA
    TAY
    SEC
    RTS
Convert_Bgk_Tile.End
    CLC
    RTS
